﻿using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Debug;
using CrawlerApp.Core.Entities.BookAggregate;
using CrawlerApp.Core.Entities;
using System.Data.Common;

namespace CrawlerApp.Infrastructure.Data
{
    public class ApplicationDbContext: DbContext
    {
        //private readonly static LoggerFactory loggerFactory = new LoggerFactory(new[] { new DebugLoggerProvider() });
        public ApplicationDbContext() : base() { }
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }
        protected override void OnConfiguring(DbContextOptionsBuilder options)
        {
            //options.UseSqlite("Data Source=crawler.loc", o => o.CommandTimeout(30));
            options.UseSqlServer(@"Server=(localdb)\MSSQLLocalDB;Database=crawler;Trusted_Connection=True;MultipleActiveResultSets=true");
            //options.EnableSensitiveDataLogging(true);
            //options.UseLoggerFactory(loggerFactory);
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());

        }

        public override int SaveChanges()
        {
            ApplyConcepts();
            return base.SaveChanges();
        }

        public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
        {
            ApplyConcepts();
            return await base.SaveChangesAsync(cancellationToken);
        }

        #region SaveChanges 添加记录时自动增加创建时间
        private void ApplyConcepts()
        {
            foreach(var entity in ChangeTracker.Entries().ToList())
            {
                if(entity.State == EntityState.Added)
                {
                    // CreateDateTime 是在基类中的，一个一个改太麻烦了
                    if (entity.Properties.Any(p => p.Metadata.Name == "CreateDateTime"))
                        entity.Property("CreateDateTime").CurrentValue = DateTime.UtcNow;
                }
                if(entity.State == EntityState.Deleted)
                {
                    if (entity.Entity.GetType().Equals(typeof(Book)))
                    {
                        var deleted = entity.Properties.SingleOrDefault(p => p.Metadata.Name == "Deleted");
                        if (deleted != null && deleted.CurrentValue != true as object)
                        {
                            entity.Property("Deleted").CurrentValue = true;
                            entity.State = EntityState.Modified;
                        }
                    }
                }
            }
        }
        #endregion
    }
}
